# minorlex.py

from sly import Lexer

class MinorLexer(Lexer):
    # Set of token names. This is always required

    tokens = { 
        NUMBER, 
        BOOL
        ID, 
        WHILE, 
        IF, 
        ELSE,
        PRINT, 
        PLUS, 
        MINUS, 
        TIMES, 
        DIVIDE, 
        ASSIGN,
        EQ, 
        LT, 
        LE, 
        GT, 
        GE, 
        NE
    }

    literals = { '(', ')', '{', '}', ';' ,':'}

    # String containing ignored characters
    ignore = ' \t'

    # Regular expression rules for tokens
    PLUS	= r'\+'
    MINUS	= r'-'
    TIMES	= r'\*'
    DIVIDE = r'/'
    EQ	= r'=='
    ASSIGN = r'='
    LE	= r'<='
    LT	= r'<'
    GE	= r'>='
    GT	= r'>'
    NE	= r'!='

    @_(r'\d+')
    def NUMBER(self,t):
        t.value = int(t.value) 
        return t

    @_(r'(True)|(False)')
    def BOOL(self, t):
        t.value = if t.value=='True' True else False
        return t

    # Identifiers and keywords
    ID = r'[a-zA-Z_][a-zA-Z0-9_]*'
    ID['if'] = IF
    ID['else'] = ELSE
    ID['while'] = WHILE
    ID['print'] = PRINT

    ignore_comment = r'\#.*'

    # Line number tracking
    @_(r'\n+') 
    def ignore_newline(self, t):
        self.lineno += t.value.count('\n')

    def error(self, t): 
        print('Line %d: Bad character %r' % (self.lineno, t.value[0]))
        self.index += 1

if __name__ == '__main__':
    data = '''
# Counting x = 0; 
while (x < 10) { 
    print x;
    x = x + 1;
}
    '''
    lexer = MinorLexer()
    for tok in lexer.tokenize(data):
        print(tok)